package com.hanxiaozhang.example.listener.mgssend;

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.support.RocketMQHeaders;


/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author hanxinghua
 * @create 2022/10/8
 * @since 1.0.0
 */
@Slf4j
public class No6LocalTransactionOriginalSyntaxListener implements TransactionListener {


    /**
     * 执行本地事务
     * <p>
     * 这里的半消息，此时消息只是被保存到Broker，并没有发送到Topic中，
     * Broker根据本地返回的状态来决定消息的处理方式。
     *
     * @param msg
     * @param arg
     * @return
     */
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        String type = msg.getProperty("type");
        if ("0".equals(type)) {
            String msgKey = msg.getProperty("msgKey");
            switch (msgKey) {
                case "1":
                    // 回滚操作，消息将会被删除，不允许被消费。
                    return LocalTransactionState.ROLLBACK_MESSAGE;
                case "2":
                    // 消息无响应，需要回查本地事务状态来决定是提交还是回滚事务
                    return LocalTransactionState.UNKNOW;
                default:
                    // 消息通过，允许消费者消费消息
                    return LocalTransactionState.COMMIT_MESSAGE;
            }
        } else {
            return LocalTransactionState.COMMIT_MESSAGE;
        }
    }


    /**
     * MQ回调检查本地事务执行情况
     * <p>
     * 返回状态：
     * COMMIT_MESSAGE：提交事务，允许消费者消费该消息
     * ROLLBACK_MESSAGE：回滚事务，消息将被丢弃不允许消费。
     * UNKNOW：暂时无法判断状态，等待固定时间以后Broker端根据回查规则向生产者进行消息回查。
     *
     * @param msg
     * @return
     */
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {

        String type = msg.getProperty("type");
        if ("0".equals(type)) {
            log.info("回查本地事务状态：transactionId:[{}],消息Key:[{}]", msg.getProperty(RocketMQHeaders.TRANSACTION_ID), msg.getProperty("msgKey"));
            return LocalTransactionState.COMMIT_MESSAGE;
        } else {
            log.info("开始执行回查");
            // todo
            log.info("提交半消息");
            return LocalTransactionState.COMMIT_MESSAGE;
        }
    }
}